package cc.admin.modules.sys.util;

import cc.admin.common.constant.WeChatConstant;
import cc.admin.common.constant.WeChatTemplateConstant;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 微信公众号工具类
 * The type We chat util.
 */
public class WeChatUtil {

	/**
	 * 发送内容只能有20个字符
	 * @param content
	 * @return
	 */
	public static String getContent(String content){
		if (StrUtil.isNotEmpty(content)) {
			if (content.length() > 20) {
				return content.substring(0, 20);
			}
		}
		return content;
	}

    /**
     * The entry point of application.
     *
     * @param args the input arguments
     */
    public static void main(String[] args) {
        String phones = "oVGpL5kVTV76YoeH5GzaY3VOrbqY";

        for (String phone : phones.split(",")) {

            JSONObject data = new JSONObject();
            JSONObject wtype = new JSONObject();
            wtype.put("value", "大风预警");//天气类型
            data.put("short_thing2", wtype);
            JSONObject yjdj = new JSONObject();
            yjdj.put("value", "蓝色预警"); //预警等级
            data.put("short_thing3", yjdj);
            JSONObject fbsj = new JSONObject();
            fbsj.put("value", "2023-08-25 13时23分");//发布时间
            data.put("time4", fbsj);

            JSONObject tqlx = new JSONObject();
            //String weatherType =map.get("weather").toString();

            tqlx.put("value", "25日白天至27日夜间，受台风“苏拉”影"); //天气类型
            data.put("thing6", tqlx);

            JSONObject sjfw = new JSONObject();
            sjfw.put("value", "黄海海域"); //涉及范围
            data.put("thing7", sjfw);

            System.out.println(data);
            sendTemplateMsg(phone, WeChatTemplateConstant.WEATHER_TEMPLATEID, data);
//            send(phone , "您好,欢迎来到河北东来工程技术有限公司! 测试是否能获取到手机号");
        }

    }

    /**
     * 获取微信公众号的AccessToken
     *
     * @return accessToken access token
     */
    public static String getAccessToken() {
        String accessToken = "";
        String url = WeChatConstant.ACCESS_TOKEN_URL;

        try {
            URL urlObj = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) urlObj.openConnection();

            connection.setRequestMethod("GET");
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.connect();

            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            String line;
            StringBuilder sb = new StringBuilder();

            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            System.out.println("sb=================" + sb);
            reader.close();
            connection.disconnect();

            JSONObject json = JSONObject.parseObject(sb.toString());
            accessToken = json.getString("access_token");
        } catch (Exception e) {
            e.printStackTrace();
        }

        return accessToken;
    }

    /**
     * 获取关注者列表
     *
     * @param accessToken 接口调用凭证
     * @return JsonObject user list
     */
    public static List<String> getUserList(String accessToken) {
        String url = WeChatConstant.USER_LIST_URL + accessToken;

        HttpURLConnection connection = null;
        try {
            URL urlObj = new URL(url);
            connection = (HttpURLConnection) urlObj.openConnection();
            connection.setRequestMethod("GET");
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.connect();

            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            String line;
            StringBuilder sb = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }

            reader.close();
            connection.disconnect();

            JSONObject json = JSONObject.parseObject(sb.toString());
            List<String> openIds = json.getJSONObject("data").getJSONArray("openid").toJavaList(String.class);
            return openIds;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }

        return null;
    }

    /**
     * 向指定的用户发送文本消息
     *
     * @param accessToken 微信公众号的accessToken
     * @param openId      用户的openid
     * @param content     发送的文本内容
     * @throws IOException the io exception
     */
    public static void sendTextMessage(String accessToken, String openId, String content) throws IOException {

        String url = WeChatConstant.SEND_CUSTOMER_SERVICE_MSG + accessToken;

        String data = "{\"touser\":\"" + openId + "\",\"msgtype\":\"text\",\"text\":{\"content\":\"" + content + "\"}}";


        // 发送请求
        try {
            URL urlObj = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) urlObj.openConnection();
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.connect();
            OutputStream os = conn.getOutputStream();
            os.write(data.getBytes("UTF-8"));
            os.flush();
            os.close();
            InputStream is = conn.getInputStream();
            int size = is.available();
            byte[] jsonBytes = new byte[size];
            is.read(jsonBytes);
            String message = new String(jsonBytes, "UTF-8");
            System.out.println(message);
            is.close();
            conn.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 向指定的用户发送消息
     *
     * @param phone   用户的phone
     * @param content 发送的内容
     * @return 发送结果的json字符串
     * @throws IOException
     */
    public static void send(String phone, String content) {
//        JdbcTemplate jdbcTemplate = ApplicationContextUtil.getContext().getBean(JdbcTemplate.class);
        //获取微信公众号的AccessToken
        String accessToken = getAccessToken();
//        //获取关注者列表
//        List<String> openIds = getUserList(accessToken);

        try {
            List<Entity> users = Db.use().query("select openid from wx_gzh_user where phone=?", phone);

            if (!users.isEmpty()) {
                //调用发送消息的接口
                sendTextMessage(accessToken, users.get(0).get("openid").toString(), content);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    /**
     * Send template msg.
     *
     * @param openid     the phone
     * @param templateId the template id
     * @param data       the data
     */
    public static void sendTemplateMsg(String openid, String templateId, JSONObject data) {
        // 获取access_token
        String accessToken = getAccessToken();
        // 组装模板消息
        List<Entity> users = null;
        try {
            //JdbcTemplate jdbcTemplate = ApplicationContextUtil.getContext().getBean(JdbcTemplate.class);
            //后续需要把Db换成jdbc查询
            //users = Db.use().query("select openid from wx_gzh_user where phone=?", phone);
           /* if(!users.isEmpty()){
                String openid = users.get(0).get("openid").toString();*/

            JSONObject templateMessage = new JSONObject();
            templateMessage.put("touser", openid);
            templateMessage.put("template_id", templateId);
            templateMessage.put("data", data);
            StringEntity entity = new StringEntity(templateMessage.toJSONString(), "utf-8");
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            // 发送模板消息
            String sendUrl = WeChatConstant.SEND_TEMPLATE_MSG + accessToken;
            HttpPost httpPost = new HttpPost(sendUrl);
            httpPost.setEntity(entity);
            // 处理API响应
            CloseableHttpClient httpClient = HttpClients.createDefault();
            CloseableHttpResponse response = httpClient.execute(httpPost);
            String result = EntityUtils.toString(response.getEntity());
            System.out.println(result);
            //}
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * Http request string.
     *
     * @param requestUrl    the request url
     * @param requestMethod the request method
     * @param output        the output
     * @return the string
     */
    public static String httpRequest(String requestUrl, String requestMethod, String output) {
        try {
            URL url = new URL(requestUrl);
            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setRequestMethod(requestMethod);
            if (null != output) {
                OutputStream outputStream = connection.getOutputStream();
                outputStream.write(output.getBytes(StandardCharsets.UTF_8));
                outputStream.close();
            }
            // 从输入流读取返回内容
            InputStream inputStream = connection.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str;
            StringBuilder buffer = new StringBuilder();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            connection.disconnect();
            return buffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url  发送请求的 URL
     * @param json 请求参数，请求参数应该是 json 的形式。
     * @return 所代表远程资源的响应结果 string
     */
    public static String httpPost(String url, JSONObject json) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(json);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result = result.concat(line);
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

}
